package com.egg.auth.controller.web;

import cn.dev33.satoken.oauth2.model.AccessTokenModel;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.egg.common.core.enums.ResponseCode;
import com.egg.common.core.model.controller.WebController;
import com.egg.common.core.model.response.ResponseData;
import com.egg.common.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;


@Api(tags = WebController.API_PREFIX + "Oauth2授权客户端中心")
@RestController
@RequestMapping("/client/oauth2")
public class WebOAuth2ClientController extends WebController {

    // 相关参数配置 - 从配置文件中读取
    private String clientId = "1";// 应用id
    private String clientSecret = "1";// 应用秘钥
    private String serverUrl = "http://localhost:9000";// 服务端接口

    // 进入首页
    @RequestMapping(value = "/index")
    public Object index(HttpServletRequest request) {
        request.setAttribute("uid", StpUtil.getLoginIdDefaultNull());
        return new ModelAndView("oauth2Client.html");
    }

    // 根据Code码 获取 Access-Token 和 openid
    @PostMapping("/access-token/code")
    public ResponseData accessTokenByCode(@RequestBody JSONObject jsonParam) {
        // 调用Server端接口，获取 Access-Token 以及其他信息
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("grant_type", "authorization_code");
        paramMap.put("code", jsonParam.getString("code"));
        paramMap.put("client_id", clientId);
        paramMap.put("client_secret", clientSecret);
        String str = HttpUtil.post(serverUrl + "/oauth2/token", paramMap);
        JSONObject json = JsonUtil.objToJson(str);
        ResponseData rd = JsonUtil.objToObj(str, ResponseData.class);
        if (Objects.equals(json.getInteger("code"), 200)) {
            rd.setCode(ResponseCode.SUCCESS.getCode());
        } else {
            rd.setCode(ResponseCode.SYSTEM_ERROR.getCode());
        }
        /*
        {
            "access_token":"twvfLfuqQermFNlO2ZdFOtG5FzMKGGNbkojqSQTmGVhJjfymadgczH0rSaea",
            "refresh_token":"7jRzri9vqqxgXsEeJijSYzUpcz3R9m9935mBByNnti5r23Rrf57dc4QGGUcF",
            "refresh_expires_in":"2591999",
            "openid":"1_1470557951159832576",
            "scope":"",
            "expires_in":"7199",
            "client_id":"1"
        }
        */
        return rd;
    }

    // 模式三：密码式-授权登录
    @PostMapping("/access-token/username-password")
    public ResponseData accessTokenByUsernamePassword(@RequestBody JSONObject jsonParam) {
        // 模式三：密码式-授权登录
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("grant_type", "password");
        paramMap.put("client_id", clientId);
        paramMap.put("username", jsonParam.getString("username"));
        paramMap.put("password", jsonParam.getString("password"));
        String str = HttpUtil.get(serverUrl + "/oauth2/token", paramMap);
        JSONObject json = JsonUtil.objToJson(str);
        ResponseData rd = JsonUtil.objToObj(json, ResponseData.class);
        if (Objects.equals(json.getInteger("code"), 200)) {
            rd.setCode(ResponseCode.SUCCESS.getCode());
        } else {
            rd.setCode(ResponseCode.SYSTEM_ERROR.getCode());
        }
        return rd;
    }

    // 模式四：获取应用的 Client-Token
    @PostMapping("/client-token")
    public ResponseData clientToken() {
        // 调用Server端接口
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("grant_type", "client_credentials");
        paramMap.put("client_id", clientId);
        paramMap.put("client_secret", clientSecret);
        String str = HttpUtil.get(serverUrl + "/oauth2/client_token", paramMap);
        JSONObject json = JsonUtil.objToJson(str);
        ResponseData rd = JsonUtil.objToObj(json, ResponseData.class);
        if (Objects.equals(json.getInteger("code"), 200)) {
            rd.setCode(ResponseCode.SUCCESS.getCode());
        } else {
            rd.setCode(ResponseCode.SYSTEM_ERROR.getCode());
        }
        return rd;
    }

    // 根据 Refresh-Token 去刷新 Access-Token
    @GetMapping("/access-token/refresh")
    public ResponseData accessTokenOnRefresh(
            @ApiParam(value = "refreshToken", required = true) @RequestParam(value = "refreshToken") String refreshToken
    ) {
        // 调用Server端接口，通过 Refresh-Token 刷新出一个新的 Access-Token
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("grant_type", "refresh_token");
        paramMap.put("client_id", clientId);
        paramMap.put("client_secret", clientSecret);
        paramMap.put("refresh_token", refreshToken);
        String str = HttpUtil.get(serverUrl + "/oauth2/refresh", paramMap);
        JSONObject json = JsonUtil.objToJson(str);
        ResponseData rd = JsonUtil.objToObj(json, ResponseData.class);
        if (Objects.equals(json.getInteger("code"), 200)) {
            rd.setCode(ResponseCode.SUCCESS.getCode());
        } else {
            rd.setCode(ResponseCode.SYSTEM_ERROR.getCode());
        }
        return rd;
    }

    // 根据 Access-Token 置换相关的资源: 获取账号昵称、头像、性别等信息
    @GetMapping("/getUserinfo")
    public ResponseData<AccessTokenModel> getUserinfo(
            @ApiParam(value = "accessToken", required = true) @RequestParam(value = "accessToken") String accessToken
    ) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("accessToken", accessToken);
        // 调用Server端接口，查询开放的资源
        String str = HttpUtil.get(serverUrl + "/oauth2/userinfo", paramMap);
        ResponseData rd = JsonUtil.objToObj(str, ResponseData.class);
        /*
            {
                "code":2000,
                "data":{
                    "accessToken":"dfgElBnYd0FzGM8G83m22eRWZDPiaDBUGqaENbCctSIkdtWkBIebSXpsWHdZ",
                    "clientId":"1",
                    "expiresIn":"7124",
                    "expiresTime":"1655126606987",
                    "loginId":"1470557951159832576",
                    "openid":"1_1470557951159832576",
                    "refreshExpiresIn":"2591924",
                    "refreshExpiresTime":"1657711406990",
                    "refreshToken":"MsghVOBNGdXP5ZZydXM2yOLnfLrbqut6Ek2EIUbMlF8FYyOasw9UkV0fnF38",
                    "scope":""
                },
                "error":false,
                "msg":"请求成功",
                "success":true
            }
         */
        return rd;
    }


}